import sys

import numpy as np
from PySide2.QtGui import QColor, QPen
from PySide2.QtWidgets import QApplication, QWidget
from PySide2.QtCore import QTimer, Qt
from qcustomplot_pyside2.QCustomPlot import QCP, QCustomPlot

from view.ui_widget import Ui_Widget
from src.DAQ331M import DAQ331M


class adc_demo(QWidget, Ui_Widget):
    timer_: QTimer = None
    daq331m_: DAQ331M = None
    voltage_range_: DAQ331M.DAQ_Voltage = DAQ331M.DAQ_Voltage.Voltage15V
    sample_rate_: DAQ331M.DAQ_Sample_Rate = DAQ331M.DAQ_Sample_Rate.SampleRate100K
    channel_state_: DAQ331M.DAQ_ADC_Channel = DAQ331M.DAQ_ADC_Channel.Ain_All
    channel_color_list_ = [
        QColor(Qt.black),
        QColor(Qt.red),
        QColor(Qt.blue),
        QColor(Qt.black),
        QColor(0, 197, 205),
        QColor(Qt.magenta),
        QColor(139, 69, 19),
        QColor(255, 165, 0)
    ]

    def __init__(self):
        super(adc_demo, self).__init__()
        self.setupUi(self)

        self.daq331m_ = DAQ331M()

        for var in range(0, 8):
            self.widget.addGraph()
            self.widget.graph(var).setPen(QPen(self.channel_color_list_[var], 1))
            self.widget.graph(var).setName("AIN " + str(var + 1))

        self.widget.replot()

        self.widget.xAxis.setRange(0, 1000)
        self.widget.yAxis.setRange(-5, 5)
        self.widget.setInteractions(QCP.iRangeDrag | QCP.iRangeZoom |
                                    QCP.iSelectAxes)

        self.timer_ = QTimer()
        self.timer_.timeout.connect(self.process_data)

        self.ConnectPushButton.clicked.connect(self.on_connect_push_button_clicked)
        self.StartPushButton.clicked.connect(self.on_start_push_button_clicked)
        self.StopPushButton.clicked.connect(self.on_stop_push_button_clicked)

    def process_data(self):

        enable_channel_size: int = self.daq331m_.get_adc_enable_channel_size()
        storage_depth: int = self.daq331m_.get_current_sample_rate() // enable_channel_size
        legal_channel_size: int = self.daq331m_.get_adc_legal_channel_size()

        receive_data = [np.zeros(storage_depth, dtype=np.float64) for _ in range(legal_channel_size)]

        if not self.daq331m_.adc_data_is_ready(storage_depth):
            return

        read_result: bool = True
        # 循环处理每个通道
        for channel in range(legal_channel_size):

            # 判断通道是否开启
            if not (self.channel_state_ & (1 << channel)):
                continue

            # 读取数据
            read_result = self.daq331m_.try_read_adc_data(channel, receive_data[channel], storage_depth, 1000)

            if not read_result:
                print("Error")

        x_data = np.array([1000.0 / storage_depth * var for var in range(storage_depth)])

        if read_result:
            for channel in range(legal_channel_size):
                self.widget.graph(channel).setData(x_data, receive_data[channel])
        self.widget.replot(QCustomPlot.rpQueuedReplot)

    def on_connect_push_button_clicked(self):
        self.daq331m_.delete_device()
        self.daq331m_.create_device()

        self.daq331m_.use_tcp_client_backend("192.168.1.100", 8000)

        if not self.daq331m_.initialize_device():
            print("DAQ331M设备初始化失败")
        else:
            print("DAQ331M设备初始化成功")

        if not self.daq331m_.configure_adc_parameters(self.sample_rate_, self.voltage_range_):
            print("配置DAQ331M采样率与电压失败")
        else:
            print("配置DAQ331M采样率与电压成功")

        if not self.daq331m_.configure_adc_channel(self.channel_state_):
            print("配置DAQ331M通道失败")
        else:
            print("配置DAQ331M通道成功")

    def on_start_push_button_clicked(self):
        self.timer_.setInterval(900)
        self.timer_.start()
        if self.daq331m_.start_collection():
            print("DAQ331M开始采集数据")

    def on_stop_push_button_clicked(self):
        if self.daq331m_.stop_collection():
            print("DAQ331M停止采集数据成功")
            self.timer_.stop()
        else:
            print("DAQ331M停止采集数据失败")


if __name__ == "__main__":
    app = QApplication([])
    widget = adc_demo()
    widget.show()
    sys.exit(app.exec_())
